﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using BillCalendar;


    public class PayPeriod
    {
        public DateTime PayDate
        {
            get
            {
                return Paycheck.Date;
            }
        }
        public CalendarTransaction Paycheck { get; set; }
        public List<CalendarTransaction> Bills { get; set; }
        public decimal TotalExpenses
        {
            get
            {
                return -1 * Bills.Sum(x => x.Value);
            }
        }
        public decimal TotalRemainingAfterBills
        {
            get
            {
                return Paycheck.Value - TotalExpenses;
            }
        }
        public string BillList
        {
            get
            {
                var companies = Bills.Select(x => x.Company);
                return String.Join(",", companies);
            }
        }
        public PayPeriod()
        {
            Bills = new List<CalendarTransaction>();
        }
        public PayPeriod(CalendarTransaction paycheck)
        {
            Paycheck = paycheck;
            Bills = new List<CalendarTransaction>();
        }
        public static List<PayPeriod> NormalizePayPeriods(List<PayPeriod> minimumPayoutPayPeriods)
        {
            List<PayPeriod> tempPayPeriods = minimumPayoutPayPeriods;

            decimal avgRemaining = tempPayPeriods.Select(x => x.TotalRemainingAfterBills).Average();
            for (int i = 1; i < tempPayPeriods.Count; i++)
            {
                PayPeriod previousPeriod = tempPayPeriods[i - 1];
                PayPeriod currentPeriod = tempPayPeriods[i];
                List<CalendarTransaction> billsToMove = currentPeriod.Bills.FindAll(x => Math.Abs(x.Value) > currentPeriod.Paycheck.Value).ToList<CalendarTransaction>();
                foreach (CalendarTransaction bill in billsToMove)
                {

                    currentPeriod.Bills.Remove(bill);
                    if (Math.Abs(bill.Value) / 3 < currentPeriod.Paycheck.Value)
                    {
                        CalendarTransaction[] splitBill = bill.SplitBill((decimal)0.33);
                        currentPeriod.Bills.Add(splitBill[0]);
                        previousPeriod.Bills.Add(splitBill[1]);
                    }
                    else
                        previousPeriod.Bills.Add(bill);
                }
                if (previousPeriod.TotalRemainingAfterBills < 0)
                    NormalizePayPeriods(avgRemaining, tempPayPeriods[i - 2], previousPeriod);
                NormalizePayPeriods(avgRemaining, previousPeriod, currentPeriod);
            }
            return tempPayPeriods;
        }
        public static void NormalizePayPeriods(decimal avgRemaining, PayPeriod previousPeriod, PayPeriod currentPeriod)
        {

            if ((previousPeriod.TotalRemainingAfterBills + 100) > avgRemaining)
            {

                while (currentPeriod.TotalRemainingAfterBills < 0 || (previousPeriod.TotalRemainingAfterBills > 200 && (previousPeriod.TotalRemainingAfterBills - currentPeriod.TotalRemainingAfterBills) > 100 && currentPeriod.TotalRemainingAfterBills + 50 < avgRemaining))
                {
                    decimal maxBill = (previousPeriod.TotalRemainingAfterBills - currentPeriod.TotalRemainingAfterBills) / 2;
                    if (maxBill > previousPeriod.TotalRemainingAfterBills - 200)
                        maxBill = previousPeriod.TotalRemainingAfterBills - 200;
                    List<CalendarTransaction> billToMoveChoices = currentPeriod.Bills.FindAll(x => Math.Abs(x.Value) < maxBill).OrderByDescending(x => x.Value).ToList<CalendarTransaction>();

                    if (billToMoveChoices != null && billToMoveChoices.Count() != 0)
                    {
                        CalendarTransaction billToMove = billToMoveChoices[0];
                        currentPeriod.Bills.Remove(billToMove);
                        previousPeriod.Bills.Add(billToMove);
                    }
                    else
                        break;
                }
            }
        }
    }
